﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using eeenno.ReaderEngine.Utilities;

namespace eeenno.ReaderEngine.Objects
{
    [Serializable]

    /// <summary>
    /// Encapsulates all information belonging to a Google Reader Subscription
    /// </summary>
    public class Subscription
    {
        private string _title;
        private string _url;
        private string _tag;
        private string _id;
        private int _unread_count;
        private int _index;
        private bool _is_reading_list;
        private Articles _articles;
        

        /// <summary>
        /// Creates a subscription object with the title, url, and tag information
        /// </summary>
        /// <param title="title">Subscription title</param>
        /// <param title="url">Subscription url</param>
        /// <param title="tag">Subscription tag</param>
        public Subscription(string title, string url, string tag)
        {
            _title = title;
            _url = url; 
            _tag = tag;
        }

        /// <summary>
        /// Creates a subscription object with the title, url, and tag information
        /// </summary>
        /// <param title="title">Subscription title</param>
        /// <param title="url">Subscription url</param>
        /// <param title="tag">Subscription tag</param>
        /// <param title="id">Subscription ID</param>
        public Subscription(string title, string url, string tag, string id)
        {
            _title = title;
            _url = url;
            _tag = tag;
            _id = id;
        }

        /// <summary>
        /// Creates a reading list subscription item
        /// </summary>
        /// <param name="tag_name"></param>
        public Subscription(string tag_name)
        {
            this.is_reading_list = true;
            this.title = tag_name + " Reading List";
            this.tag = tag_name;
            this.url = String.Empty;
        }

        public Subscription()
        {
        }

        public bool articles_loaded
        {
            get { return _articles != null; }
        }

        public string url
        {
            get { return _url; }
            set { _url = value; }
        }

        public string title
        {
            get { return _title; }
            set { _title = value; }
        }

        public string tag
        {
            get { return _tag; }
            set { _tag = value; }
        }

        public string id
        {
            get { return _id; }
            set { _id = value; }
        }

        public string continuation
        {
            get { return _articles.continuation; }
        }

        public int unread_count
        {
            get { return _unread_count; }
            set { _unread_count = value; }
        }

        public bool is_reading_list
        {
            get { return _is_reading_list; }
            set { _is_reading_list = value; }
        }

        public int article_count
        {
            get 
            {
                if (_articles != null)
                {
                    return _articles.Count;
                }
                else
                {
                    return 0;
                }
            }
        }

        public Articles GetRange(int start, int length)
        {
            Articles ret_val = new Articles();
            ret_val.continuation = this.continuation;
            for(int i = 0; i < length; i++)
            {
                if ((start + i) < _articles.Count)
                {
                    ret_val.Add(_articles.Get(start + i));
                }
                else
                {
                    break;
                }
            }
            return ret_val;
        }

        public Articles articles
        {
            set { _articles = value; }
            get { return _articles; }
        }       

        /// <summary>
        /// Loads/refreshes articles from internet
        /// </summary>
        /// <param name="first_refresh"></param>
        public int RefreshArticles(bool first_refresh)
        {
            Articles articles = null;
            if (is_reading_list == true)
            {
                if (first_refresh || _articles == null)
                {
                    if (_articles == null)
                        _articles = new Articles();
                    articles = SpeeedReader.GetArticlesByTag(_tag, Settings.download_size);
                    _articles.continuation = articles.continuation;
                }
                else
                {
                    string timestamp = String.Empty;
                    try
                    {
                        timestamp = _articles.GetLatestUnixTimeStamp();
                    }
                    catch (FormatException e)
                    {
                    }
                    if (timestamp.Length > 0)
                    {
                        articles = SpeeedReader.GetArticlesByTag(_tag, timestamp);
                    }
                }
            }
            else
            {
                if (first_refresh)
                {
                    if(_articles == null)
                        _articles = new Articles();
                    articles = SpeeedReader.GetArticlesByFeed(_url, Settings.download_size);
                    _articles.continuation = articles.continuation;
                }
                else
                {
                    string timestamp = String.Empty;
                    try
                    {
                        if (_articles != null)
                        {
                            timestamp = _articles.GetLatestUnixTimeStamp();
                            if (timestamp.Length > 0)
                            {
                                articles = SpeeedReader.GetArticlesByTimestamp(url, timestamp);
                            }
                        }
                        else
                        {
                            _articles = new Articles();
                            articles = SpeeedReader.GetArticlesByFeed(_url, Settings.download_size);
                        }
                    }
                    catch (FormatException e)
                    {
                    }                    
                }
            }
            _articles.Add(articles, false, false);
            //prevents the article from growing out of control is the user so chooses
            if (Settings.max_articles_to_cache > 0)
            {
                _articles.Sort();
                _articles = GetRange(0, Settings.max_articles_to_cache);
            }
            RefreshUnreadCount();
            return article_count;
        }

        public void RefreshUnreadCount()
        {
            _unread_count = 0;
            if (_articles != null)
            {
                for (int i = 0; i < _articles.Count; i++)
                {
                    if (_articles.Get(i).unread)
                    {
                        _unread_count++;
                    }
                }
            }
        }

        private Articles GetArticles()
        {
            if (_articles == null)
            {
                if (_is_reading_list)
                {
                    _articles = SpeeedReader.GetArticleByTag(tag);
                }
                else
                {
                    _articles = SpeeedReader.GetArticlesByFeed(_url, Settings.download_size);
                }            
                return _articles;
            }
            else
            {
                return _articles;
            }
        }

        public int index
        {
            get { return _index; }
            set { _index = value; }
        }
    }
}
